package com.feng.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Validator {
	
	private static final String emailAddressPattern = "\\b(^['_A-Za-z0-9-]+(\\.['_A-Za-z0-9-]+)*@([A-Za-z0-9-])+(\\.[A-Za-z0-9-]+)*((\\.[A-Za-z0-9]{2,})|(\\.[A-Za-z0-9]{2,}\\.[A-Za-z0-9]{2,}))$)\\b";
	private final static String mobilePattern = "^((13[0-9])|(15[^4,\\D])|(18[0-9])|(14[5,7])|(17[7,8]))\\d{8}$";
	/**
	 * Validate integer.
	 */
	public static boolean validateInteger(String value, int min) {
		try {
			int temp = Integer.parseInt(value);
			if (temp < min) {
				return false;
			}
			return true;	
		}
		catch (Exception e) {
			return false;
		}
	}
	/**
	 * Validate integer.
	 */
	public static boolean validateInteger(String value, int min, int max) {
		try {
			int temp = Integer.parseInt(value);
			if (temp < min || temp > max) {
				return false;
			}
			return true;	
		}
		catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * Validate long.
	 */
	public static boolean validateLong(String value, long min, long max) {
		try {
			
			long temp = Long.parseLong(value);
			if (temp < min || temp > max)
				return false;
			
			return true;
		}
		catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * Validate long.
	 */
	public static boolean validateLong(String value) {
		try {
			Long.parseLong(value);
			
			return true;
		}
		catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * Validate double.
	 */
	public static boolean validateDouble(String value, double min) {
		try {
			double temp = Double.parseDouble(value);
			if (temp < min)
				return false;
			
			return true;
		}
		catch (Exception e) {
			return true;
		}
	}
	
	/**
	 * Validate double.
	 */
	public static boolean validateDouble(String value, double min, double max) {
		try {
			double temp = Double.parseDouble(value);
			if (temp < min || temp > max)
				return false;
			
			return true;
		}
		catch (Exception e) {
			return true;
		}
	}
	
	/**
	 * Validate double.
	 */
	public static boolean validateDouble(String value) {
		try {
			Double.parseDouble(value);
			
			return true;
		}
		catch (Exception e) {
			return false;
		}
	}
	
	/** 
	 * Validate date.
	 */
	public static boolean validateDate(String value, Date min) {
		try {
			Date temp = new SimpleDateFormat(datePattern).parse(value);	// Date temp = Date.valueOf(value); 涓轰簡鍏煎 64浣�JDK
			if (temp.before(min))
				return false;
			
			return true;
		}
		catch (Exception e) {
			return false;
		}
	}
	
	/** 
	 * Validate date.
	 */
	public static boolean validateDate(String value, Date min, Date max) {
		try {
			Date temp = new SimpleDateFormat(datePattern).parse(value);	// Date temp = Date.valueOf(value); 涓轰簡鍏煎 64浣�JDK
			if (temp.before(min) || temp.after(max))
				return false;
			
			return true;
		}
		catch (Exception e) {
			return false;
		}
	}
	
	// TODO set in Const and config it in Constants. TypeConverter do the same thing.
	private static final String datePattern = "yyyy-MM-dd";
	
	/** 
	 * Validate date. Date formate: yyyy-MM-dd
	 */
	public static boolean validateDate(String value, String min, String max) {
		// validateDate(field, Date.valueOf(min), Date.valueOf(max), errorKey, errorMessage);  涓轰簡鍏煎 64浣�JDK
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
			
			return validateDate(value, sdf.parse(min), sdf.parse(max));
		} catch (ParseException e) {
			return false;
		}
	}
	
	/**
	 * Validate equal field. Usually validate password and password again
	 */
	public static boolean validateEqualField(String value_1, String value_2) {
		if (value_1 == null || value_2 == null || (! value_1.equals(value_2)))
			return false;
		
		return true;
	}
	
	/**
	 * Validate equal string.
	 */
	public static boolean validateEqualString(String s1, String s2) {
		if (s1 == null || s2 == null || (! s1.equals(s2)))
			return false;
		
		return true;
	}
	
	/**
	 * Validate equal integer.
	 */
	public static boolean validateEqualInteger(Integer i1, Integer i2) {
		if (i1 == null || i2 == null || (i1.intValue() != i2.intValue()))
			return false;
		
		return true;
	}
	
	/**
	 * Validate email.
	 */
	public static boolean validateEmail(String value) {
		return validateRegex(value, emailAddressPattern, false);
	}
	
	/**
	 * Validate URL.
	 */
	public static boolean validateUrl(String value) {
		try {
			if (value.startsWith("https://"))
				value = "http://" + value.substring(8); // URL doesn't understand the https protocol, hack it
			new URL(value);
			
			return true;
		} catch (MalformedURLException e) {
			return false;
		}
	}
	
	/**
	 * Validate regular expression.
	 */
	public static boolean validateRegex(String value, String regExpression, boolean isCaseSensitive) {
        if (value == null) {
        	return false;
        }
        Pattern pattern = isCaseSensitive ? Pattern.compile(regExpression) : Pattern.compile(regExpression, Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(value);
        if (!matcher.matches())
        	return false;
        
        return true;
	}
	
	/**
	 * Validate regular expression and case sensitive.
	 */
	public static boolean validateRegex(String value, String regExpression) {
		return validateRegex(value, regExpression, true);
	}
	
	public static boolean validateString(String value, boolean notBlank, int minLen, int maxLen) {
		if (value == null || value.length() < minLen || value.length() > maxLen) 
			return false;
		else if(notBlank && "".equals(value.trim()))
			return false;
		
		return true;
	}
	
	/**
	 * Validate string.
	 */
	public static boolean validateString(String field, int minLen, int maxLen) {
		return validateString(field, true, minLen, maxLen);
	}
	
	public static boolean validateMobile(String value) {
		return validateRegex(value, mobilePattern, false);
	}
}
